package net.pulseproject.router.modules.logic.beatstabilizer.old.approach2;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class OLD2_BeatHistory {
	
	private static final Log LOG = LogFactory.getLog(OLD2_BeatHistory.class);
	public static final long NOT_ENOUGH_DATA = -42;
	
	private List<Long> beats = new LinkedList<Long>();
	
	public synchronized void addBeat() {
		this.beats.add(Long.valueOf(System.currentTimeMillis()));
		long recentDuration;
		if(this.beats.size() < 2) recentDuration = -1;
		else {
			recentDuration = this.beats.get(this.beats.size() - 1).longValue() -
							 this.beats.get(this.beats.size() - 2).longValue();
		}
		LOG.trace("addBeat() ... recentDuration (ignoring gaps): " + recentDuration);
	}
	
	public synchronized long calcAverageDuration() {
		this.removeOldBeats();
		
		if(this.beats.size() < 2) {
			LOG.trace("calcAverageDuration() ... returning -1, as no up2date history data is available");
			return NOT_ENOUGH_DATA;
		}
		
		// compute average duration for recent beats
		long result = -1;
		for (int i = 1; i < this.beats.size(); i++) {
			long beatTimestamp1 = this.beats.get(i - 1).longValue();
			long beatTimestamp2 = this.beats.get(i).longValue();
			long diff = beatTimestamp2 - beatTimestamp1;
			if(result == -1) {
				result = diff;
			} else {
				result = (result + diff) / 2;
			}
		}
		
		LOG.trace("calcAverageDuration() ... returning average of "+result+" for "+this.beats.size()+" beats");
		return result;
	}
	
	private void removeOldBeats() {
		Set<Long> tooOld = new HashSet<Long>();
		long time = System.currentTimeMillis();
		for (Long beat : this.beats) {
			long diff = time - beat.longValue();
			if(diff > 3000) { // FIXME which is the global time duration for a beat to be still valid?
				tooOld.add(beat);
			}
		}
		LOG.trace("removeOldBeats() ... removing " + tooOld.size() + " beat(s)");
		this.beats.removeAll(tooOld);
	}
}
